﻿<?php

/**
 * Класс-прослойка с mysqli
 * @author Yura
 *
 */

interface iDatabase{
	public function Clear();
	// make sure there's nothing in the list
	
	public function AddQuery($query,$param=NULL,$tablenames=NULL);
	// returns true if the number of queries is equal to count($param)
	// returns false if not

	public function Execute();
	// connect; escape input; query; save result; disconnect;
	// does not return anything but
	// returns result array OR NULL if there are errors
	
	public function __construct($host,$user,$pass,$base,$encoding='cp1251',$debug=false);
}

class Database implements iDatabase{
	private $host			;
	private $base			;
	private $user			;
	private $pass			;

	private $DB				; // mysqli type
	private $result			; // last execute result array

	private $query_list		;
	private $encoding		;


	private function EscapeInjection($param){
		// this function must be called ONLY if there is a live mysql connection
		// due to mysqli_real_escape_string specific
		if(!get_magic_quotes_gpc()) $param = $this->DB->real_escape_string($param);
		return "'".$param."'";
	}

	public function __construct($host,$user,$pass,$base,$encoding='cp1251',$debug=false){
		$this->host			= $host;
		$this->user			= $user;
		$this->pass			= $pass;
		$this->base			= $base;
		$this->result		= array();
		$this->query_list	= array();
		$this->encoding		= $encoding;
		$this->debug        = $debug;

		$this->DB 			= new mysqli($this->host,$this->user,$this->pass,$this->base);
		if (mysqli_connect_error())	throw new DataError(0);

		$this->DB->query("SET NAMES ".$this->encoding);
	}

	public function __destruct(){
		$this->DB->close();
	}

	public function Clear(){
		$this->result		= array();
		$this->query_list	= array();
	}
	
	public function AddQuery($query,$param=NULL,$tablenames=NULL){					
		if(preg_match_all("/%s/",$query,$matches) != count($param)){
			throw new DataError(1,array(count($param),$query));
		}
		if(preg_match_all("/%t/",$query,$matches) != count($tablenames)){
			throw new DataError(1,array(count($tablenames),$query));
		}
		
		$new_query = $query;
		if($param!=NULL){
			if(is_array($param)){
				foreach($param as $key=>$value){
					$new_query = preg_replace("/%s/",$this->EscapeInjection($value),$new_query,1);
				}
			}
			else $new_query = preg_replace("/%s/",$this->EscapeInjection($param),$new_query,1);
		}
		
		if($tablenames!=NULL){
			if(is_array($tablenames)){
				foreach($tablenames as $key=>$value){
					$new_query = preg_replace("/%t/",'`'.$value.'`',$new_query,1);
				}
			}
			else $new_query = preg_replace("/%t/",'`'.$tablenames.'`',$new_query,1);
		}		
		
		$this->query_list[]=$new_query;
		if($this->debug) echo '<b>Query Added:</b><br>'.$new_query.'<br>';
		return true;
	}

	public function Execute(){
		$this->result=array();

		if(count($this->query_list)==0) throw new DataError(2);

		$multiquery	= '';
		foreach($this->query_list as $value) $multiquery.=$value.';';
		$this->DB->multi_query($multiquery);
		if($this->debug) echo '<b>Result Query:</b><br>'.$multiquery.'<br>';

		// чтение результатов
		$i=0;
		do{
			$temp_result=$this->DB->use_result();
			if($temp_result===false){
				// query did not return anything
				// sometimes it happens so e.g. for INSERT
				$this->result[$i]=NULL;
				$i++;
				continue;
			}
			while ($row = $temp_result->fetch_array(MYSQLI_ASSOC)) {
				$this->result[$i][]=$row;
			}
			$temp_result->close();
			$i++;
		}while($this->DB->next_result());

		$querynum = count($this->query_list);
		// лучшего способа проверить наличие ошибки НЕТ
		if($i<count($this->query_list)){
			throw new DataError(3,$this->error.':: '.$multiquery);
		}

		// возвращение результата

		$this->query_list = array();
		if($querynum == 1) return array_pop($this->result);
		return $this->result;
	}
}
?>